package com.gl.glcourses.services.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.gl.glcourses.calendar.ICalendarManager;
import com.gl.glcourses.mail.impl.SendAprobacionParticipante;
import com.gl.glcourses.mail.impl.SendAvisoInscripcion;
import com.gl.glcourses.mail.impl.SendAvisoInscripciones;
import com.gl.glcourses.mail.impl.SendDesaprobacionParticipante;
import com.gl.glcourses.repository.ICalendarRepository;
import com.gl.glcourses.repository.IEdicionCursoRepository;
import com.gl.glcourses.repository.IParticipanteRepository;
import com.gl.glcourses.services.IParticipanteServices;
import com.gl.glcourses.vos.Confirmacion;
import com.gl.glcourses.vos.EdicionCurso;
import com.gl.glcourses.vos.EstadoEdicionCurso;
import com.gl.glcourses.vos.EstadoParticipante;
import com.gl.glcourses.vos.Participante;
import com.gl.glcourses.vos.Usuario;
import com.gl.glcourses.vos.constants.Constants;

@Service
@RemotingDestination(channels = { "my-amf" })
@Transactional
public class ParticipanteServices implements IParticipanteServices {
	
	@Autowired
	IParticipanteRepository repoParticipante;
	@Autowired
	IEdicionCursoRepository repoEdicionCurso;
	@Autowired
	SendAvisoInscripcion sendAvisoInscripcion;
	@Autowired
	SendAprobacionParticipante sendAprobacionParticipante;
	@Autowired
	SendDesaprobacionParticipante sendDesaprobacionParticipante;
	@Autowired
	SendAvisoInscripciones sendAvisoInscripciones;
	@Autowired
	ICalendarManager managerCalendar;
	@Autowired
	ICalendarRepository repoCalendar;
	
	
	//Buscamos los participantes en relacion con un PM
	//traemos los que estan pendiendes de aprobacion y los que
	//su edicionCurso no haya comenzado todavia
	@Override
	public List<Participante> listarInscripcionesPendientes(Usuario pm) throws Exception{
		
		List<Participante> participantesPendientes = repoParticipante.listarParticipantesPorEstadoPorPM(pm);
		
		for(Participante participante : participantesPendientes){
			if(participante.getEdicionCurso().getEstadoEdicionCurso() == EstadoEdicionCurso.DICTADO){
				participantesPendientes.remove(participante);
			}
		}
		return participantesPendientes;
	}
	
	@Override
	public List<Participante> listarParticantesCursosPublicados(Usuario pm) throws Exception {
		List<Participante> participantesActuales = new ArrayList<Participante>();
		participantesActuales= repoParticipante.listarParticipantesXEstadoEdicion(EstadoEdicionCurso.PUBLICADO,pm);
		return repoParticipante.getListEntity(Participante.class);
	}
	

	@Override
	public Confirmacion aprobarParticipante(Participante participante) throws Exception {
		Confirmacion confirmacion = new Confirmacion();
		Participante participanteBD = (Participante)repoParticipante.findById(participante.getId(), Participante.class); 
		if(participanteBD.getEstadoParticipante() != participante.getEstadoParticipante()){
			repoParticipante.saveUpdate(participante);

			SimpleMailMessage msg = new SimpleMailMessage();
			Map<Object, Object> hTemplateVariables = new HashMap<Object, Object>();
			hTemplateVariables.put(Constants.USUARIO_PM, participante.getUsuario());
			hTemplateVariables.put(Constants.EDICIONCURSO, participante.getEdicionCurso());
			msg.setSubject("Respuesta de Inscripcion");
			
			//if(participante.getEstadoParticipante()==EstadoParticipante.ACEPTADO){
				sendAprobacionParticipante.send(msg, hTemplateVariables);
			//}
			EdicionCurso edicion;
			edicion=participante.getEdicionCurso();
			//agrega al calendar el participante invitado
			List<Participante> participantes=new ArrayList<Participante>();
			edicion.setParticipantes(participantes);
	        saveParticipantesInvitados(participantes);
			managerCalendar.agregarInvitado(participante, repoCalendar.getSesionEdicionCursoCalendarEvent(edicion));
			
		}

		
		confirmacion.setEstado(Constants.CONFIRMACION_OK);
		return confirmacion;
	}
	
	@Override
	public Confirmacion desaprobarParticipante(Participante participante) throws Exception {
		Confirmacion confirmacion = new Confirmacion();
		Participante participanteBD = (Participante)repoParticipante.findById(participante.getId(), Participante.class); 
		if(participanteBD.getEstadoParticipante() != participante.getEstadoParticipante()){
			repoParticipante.saveUpdate(participante);

			SimpleMailMessage msg = new SimpleMailMessage();
			Map<Object, Object> hTemplateVariables = new HashMap<Object, Object>();
			hTemplateVariables.put(Constants.USUARIO_PM, participante.getUsuario());
			hTemplateVariables.put(Constants.EDICIONCURSO, participante.getEdicionCurso());
			msg.setSubject("Respuesta de Inscripcion");
			
			if(participante.getEstadoParticipante()==EstadoParticipante.RECHAZADO){
				sendDesaprobacionParticipante.send(msg, hTemplateVariables);
			}
		}
		//falta que si lo apruebo y lo desapruebo lo deberia borrar del calendar
		confirmacion.setEstado(Constants.CONFIRMACION_OK);
		return confirmacion;
	}
	
	@Override
	public void saveParticipantesInvitados(List<Participante> participantes) throws Exception {
		
		for(Participante participante : participantes){
			participante.setEstadoParticipante(EstadoParticipante.ACEPTADO);
			
			participante = (Participante)repoParticipante.saveUpdate(participante);
		}
		
	}

	@Override
	public void avisoAprobacionesPendientes() throws Exception {
		List<Participante> listaParticipantes = this.listarInscripcionesPendientes();
		List<Usuario> listaManagers = new ArrayList<Usuario>();
		
		for(Participante participante : listaParticipantes){
			listaManagers.remove(participante.getUsuario().getManager());
			listaManagers.add(participante.getUsuario().getManager());
		}

		for(Usuario usuario : listaManagers){
			
			SimpleMailMessage msg = new SimpleMailMessage();
			Map<Object, Object> hTemplateVariables = new HashMap<Object, Object>();
			hTemplateVariables.put(Constants.USUARIO_PM, usuario);
			msg.setSubject("Inscripciones Pendientes");
			sendAvisoInscripciones.send(msg, hTemplateVariables);

		}			
	}

	private List<Participante> listarInscripcionesPendientes() {
		List<Participante> participantesPendientes = new ArrayList<Participante>();
		participantesPendientes = repoParticipante.listarParticipantesPorEstado(EstadoParticipante.PENDIENTE_APROBACION);
		return participantesPendientes;
	}
	


}
